import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池的类型:  Executors.newCachedThreadPool(); 快 最大（非）线程数无限大-容易CPU标高 甚至OOM（但不不太容易）
 *              Executors.newSingleThreadExecutor(); 最慢 队列无限大-容易有OOM异常
 *              Executors.newFixedThreadPool(); 慢 队列无限大-容易有OOM异常
 *  推荐使用自定义线程池。（根据业务量计算吞吐量*2）
 * 其本质都是 new ThreadPoolExecutor 只是参数不同。
 *
 * int corePoolSize, 核心线程数
 * int maximumPoolSize, 最大(非核心)线程数
 * long keepAliveTime, 线程存活时间
 * TimeUnit unit, 时间单位
 * BlockingQueue<Runnable> workQueue, 队列
 * ThreadFactory threadFactory, 线程工厂
 * RejectedExecutionHandler handler 拒绝策略
 *
 *
 * 提交优先级
 * 执行优先级
 *
 * 新创建的非核心线程执行了新任务，并未从队列获取任务：pool-1-thread-4 == 正在干活的Id : 7
 * 结果：
 * pool-1-thread-1 == 正在干活的Id : 1
 * pool-1-thread-3 == 正在干活的Id : 3
 * pool-1-thread-2 == 正在干活的Id : 2
 * pool-1-thread-3 == 正在干活的Id : 5
 * pool-1-thread-1 == 正在干活的Id : 4
 * pool-1-thread-4 == 正在干活的Id : 7
 * pool-1-thread-3 == 正在干活的Id : 8
 * pool-1-thread-2 == 正在干活的Id : 6
 */
public class ThreadPoolt {
    public static void main(String[] args) {

        /**
         * ThreadPoolExecutor(int corePoolSize,
         *                               int maximumPoolSize,
         *                               long keepAliveTime,
         *                               TimeUnit unit,
         *                               BlockingQueue<Runnable> workQueue)
         */
        ExecutorService executorService = new ThreadPoolExecutor(3, 5, 1L, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3), new ThreadPoolExecutor.AbortPolicy());


        for (int i = 1; i <= 8; i++) {
            executorService.execute(new MyTask(i));
        }

    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class MyTask implements Runnable{

        private int i;

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() +  " == 正在干活的Id : "+ i);
        }

    }
}
